package Vue;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Point;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

import Controleur.Controleur;

/**
 * Cette class permet de créer et de gérer la fenêtre principal de l'application.
 * 
 * @author Kilian Cousein et Benjamin Tardieu
 */
public class Fenetre extends JFrame
{
//======================================================================//
//============================ Variables ===============================//
//======================================================================//
	
	private Controleur controleur;
	
    private BarreMenu barreMenu;
    private BarreOption barreOption;
    private BarreEtatHaut barreEtatHaut;
    private BarreOutils barreOutils;
    private BarreEtatBas barreEtatBas;
    private ZoneDeDessin zoneDeDessin;
    
    private JScrollPane scroller;
   
    
//======================================================================//
//========================== Constructeurs =============================//
//======================================================================//
    
    /**
     * Crée une nouvelle instance de <i>Fenetre</i>.
     *
     * @param controleur
     */
    public Fenetre(Controleur controleur, String nom, int largeur, int hauteur)
    {
    	this.controleur = controleur;
    	this.setMinimumSize(new Dimension(470, 360));
    	
    	this.barreMenu = new BarreMenu(this.controleur);
    	this.barreOption = new BarreOption(this.controleur);
    	this.barreEtatHaut = new BarreEtatHaut(this.controleur);
    	this.barreOutils = new BarreOutils(this.controleur);
    	this.barreEtatBas = new BarreEtatBas(this.controleur);
    	this.zoneDeDessin = new ZoneDeDessin(this.controleur, largeur, hauteur);    	
    	
        this.setTitle(nom +" - DVect");
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);
        
        this.init();
        this.pack();
    }

    
//======================================================================//
//============================= Méthodes ===============================//
//======================================================================//
    
    /**
     * Cette class permet organiser la fenêtre. 
     */
    public void init()
    {
    	this.setJMenuBar(this.barreMenu);
    	JPanel pan = new JPanel(new BorderLayout());
    	
    	pan.add(this.barreOption,BorderLayout.NORTH);
    	pan.add(this.barreEtatHaut,BorderLayout.SOUTH);
    	this.add(pan,BorderLayout.NORTH);
    	
    	this.add(this.barreOutils,BorderLayout.WEST);
    	this.add(this.barreEtatBas,BorderLayout.SOUTH);
    	
    	this.scroller = new JScrollPane();
    	this.scroller.setViewportView(this.zoneDeDessin);
    	this.scroller.getVerticalScrollBar().setUnitIncrement(25);
    	this.scroller.getHorizontalScrollBar().setUnitIncrement(25);
    	
    	this.add(scroller, BorderLayout.CENTER);
    }
    

    /**
     * Cette méthode permet d'afficher les coordonnées de la souris, si cette dernière se trouve dans la zone de dessin.
	 * 
	 * @param x Position x de la souris.
	 * @param y Position y de la souris.
     */
    public void afficherPositionSouris(int x , int y)
    {
    	this.barreEtatBas.afficherPositionSouris(x,y); 
    }

    
    /**
     * Cette méthode permet de désactiver les éléments graphiques permettant d'enregistrer un dessin.
     */
    public void desactiverEnregistrement()
    {
    	this.barreOption.desactiverEnregistrement();
    	this.barreMenu.desactiverEnregistrement();
    }

    
    /**
     * Cette méthode permet de activer les éléments graphiques permettant d'enregistrer un dessin.
     */
    public void activerEnregistrement()
    {
    	this.barreOption.activerEnregistrement();
    	this.barreMenu.activerEnregistrement();
    }

    
    /**
     * Cette méthode permet de désactiver les éléments graphiques permettant d'annuler en évènement du dessin.
     */
    public void desactiverAnnuler()
    {
    	this.barreOption.desactiverAnnuler();
    	this.barreMenu.desactiverAnnuler();
    }
    

    /**
     * Cette méthode permet de activer les éléments graphiques permettant d'annuler en évènement du dessin.
     */
    public void activerAnnuler()
    {
    	this.barreOption.activerAnnuler();
    	this.barreMenu.activerAnnuler();
    }

    
    /**
     * Cette méthode permet de désactiver les éléments graphiques permettant de rétablir en évènement du dessin.
     */
    public void desactiverRetablir()
    {
    	this.barreOption.desactiverRetablir();
    	this.barreMenu.desactiverRetablir();
    }

    
    /**
     * Cette méthode permet de activer les éléments graphiques permettant de rétablir en évènement du dessin.
     */
    public void activerRetablir()
    {
    	this.barreOption.activerRetablir();
    	this.barreMenu.activerRetablir();
    }

    
    /**
     * Cette méthode permet d'afficher ou non, le menu pour que l'utilisateur puis modifier les caractéristiques du texte.
     * 
     * @param affiche Affiche le menu si <i>affiche</i> vaut vrai, sinon l'enlève. 
     */
    public void afficheMenuTexte(boolean affiche) 
    {
    	this.barreEtatHaut.afficheMenuTexte(affiche);
    }

    
    /**
     * Cette méthode permet d'afficher ou non, le menu pour que l'utilisateur puis modifier la largeur de la bordure.
     * 
     * @param affiche Affiche le menu si <i>affiche</i> vaut vrai, sinon l'enlève. 
     */
    public void afficheMenuLargeurBordure(boolean affiche) 
    {
    	this.barreEtatHaut.afficheMenuLargeurBordure(affiche);
    }

    
    /**
     * Cette méthode permet d'afficher ou non, le menu pour que l'utilisateur puis modifier le nombre de coté d'un polygone.
     * 
     * @param affiche Affiche le menu si <i>affiche</i> vaut vrai, sinon l'enlève. 
     */
    public void afficheMenuNbCotePolygone(boolean affiche) 
    {
    	this.barreEtatHaut.afficheMenuNbCotePolygone(affiche);
    }

    
    /**
     * Cette méthode permet d'afficher ou non, le menu pour que l'utilisateur puis modifier l'opacité d'un motif.
     * 
     * @param affiche Affiche le menu si <i>affiche</i> vaut vrai, sinon l'enlève. 
     */
    public void afficheMenuOpacite(boolean affiche) 
    {
    	this.barreEtatHaut.afficheMenuOpacite(affiche);
    }

    
    /**
     * Cette méthode permet de modifier la couleur de remplissage affiché par le menu.
     *  
     * @param couleur Nouvelle couleur.
     */
    public void modifierValeurMenuCouleurRemplissage(Color couleur)
    {
    	this.barreEtatBas.modifierValeurMenuCouleurRemplissage(couleur);
    }

    
    /**
     * Cette méthode permet de modifier la couleur de la bordure affiche par le menu.
     *  
     * @param couleur Nouvelle couleur.
     */
    public void modifierValeurMenuCouleurBordure(Color couleur)
    {
    	this.barreEtatBas.modifierValeurMenuCouleurBordure(couleur);
    }


    /**
     * Cette méthode permet de modifier la valeur de la largeur de la bordure affichée par le menu.
     * 
     * @param largeurBordure Nouvelle largeur de la bordure.
     */
    public void modifierValeurMenuBordure(int largeurBordure)
    {
    	this.barreEtatHaut.modifierValeurMenuBordure(largeurBordure);
    }


    /**
     * Cette méthode permet de modifier la valeur du nombre de coté d'um polygone affichée par le menu.
     *  
     * @param nbCotePolygone Nouvelle valeur du nombre de coté d'un polygone.
     */
    public void modifierValeurMenuNbCote(int nbCotePolygone)
    {
    	this.barreEtatHaut.modifierValeurMenuNbCote(nbCotePolygone);
    }


    /**
     * Cette méthode permet de modifier la valeur de la police affichée par le menu.
     * 
     * @param police Nouvelle valeur pour la police.
     */
    public void modifierValeurMenuPolice(String police)
    {
    	this.barreEtatHaut.modifierValeurMenuPolice(police);
    }
    
    
    /**
     * Cette méthode permet de modifier la valeur de l'opacité affichée par le menu.
     * 
     * @param opacite Nouvelle valeur pour l'opacité.
     */
    public void modifierValeurMenuOpacocite(int opacite)
    {
    	this.barreEtatHaut.modifierValeurMenuOpacocite(opacite);
    }
    
	 /**
     * Cette méthode permet de modifier la valeur de la taille de la police dans le menu lors d'un clic sur un objet de type texte
     *  
     * @param taillePolice taille du texte
     */
	public void modifierValeurMenuTaillePolice(int taillePolice) 
	{
    	this.barreEtatHaut.modifierValeurMenuTaillePolice(taillePolice);
	}
    
    
    /**
     * Cette méthode permet de changer la dimension de la zone de dessin.
     * 
     * @param dimension Nouvelle dimension de la zone de dessin.
     */
    public void changerDimensionZoneDeDessin(Dimension dimension)
    {
    	this.scroller.getVerticalScrollBar().getModel().setValue(0+scroller.getVerticalScrollBar().getValue());
    	this.scroller.getHorizontalScrollBar().getModel().setValue(0+scroller.getHorizontalScrollBar().getValue());
    	this.zoneDeDessin.changerDimensionPaneau(dimension);
    }


    /**
     * Cette méthode permet de zoomer dans la dessin.
     *  
     * @param positionSouris Position de la souris.
     * @param dimension Dimension du dessin.
     * @param zoom Zoom du dessin.
     */
    public void zoomerDessin(Point positionSouris, Dimension dimension, float zoom)
    {		
    	this.zoneDeDessin.changerDimensionPaneau(new Dimension(dimension.width * (int) zoom, dimension.height * (int) zoom));
    	//this.scroller.getHorizontalScrollBar().getModel().setValue(positionSouris.x * ((int) zoom - 1));
    	//this.scroller.getVerticalScrollBar().getModel().setValue(positionSouris.y * ((int) zoom - 1));
    }


    /**
     * Cette méthode permet de repeindre le dessin.
     */
    public void repaintDessin()
    {
    	this.zoneDeDessin.repaint();
    }

    /**
     * Cette méthode permet de retourner l'objet BarreEtatHaut
     *  
     */
	public BarreEtatHaut getBarreEtatHaut() 
	{
		return this.barreEtatHaut;
	}

    /**
     * Cette méthode permet de retourner l'objet BarreOption
     *  
     */
	public BarreOption getBarreOption() 
	{
		return this.barreOption;
	}
}